Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(files_sharing): allow not deleting expiring shares #48225

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

skjnldsv
Copy link
Member

@skjnldsv skjnldsv commented Sep 19, 2024

Fix #17996

Feature

Shares that expires are just deleted. Which leads to confusion.

  • We don't even know if the share existed or not....
  • With the new file request, we might want to extend the drop period time...
  • We need more transparency

Solution

  • Allow admins to disable share deletion on expiration (opt-in)
    2024-09-19_19-27
  • Adds a new view to list all expired shares
    image

Status

  • Add admin setting
  • Add api controller
  • Add new view
  • Add integration tests

@skjnldsv skjnldsv added this to the Nextcloud 31 milestone Sep 19, 2024
@skjnldsv skjnldsv self-assigned this Sep 19, 2024
@skjnldsv skjnldsv force-pushed the feat/disable-share-deletion branch 3 times, most recently from 099984d to 98e0fe3 Compare September 20, 2024 10:52
*/
private function getHumanBooleanConfig(string $app, string $key, bool $default = false): bool {
return $this->config->getAppValue($app, $key, $default ? 'yes' : 'no') === 'yes';
return $this->config->getAppValue($app, $key, $default ? 'yes' : 'no') !== 'no';

Check notice

Code scanning / Psalm

DeprecatedMethod

The method OCP\IConfig::getAppValue has been marked as deprecated
@skjnldsv skjnldsv force-pushed the feat/disable-share-deletion branch 8 times, most recently from d4aab4b to fda83da Compare October 9, 2024 16:19
@skjnldsv skjnldsv requested review from susnux, nfebe, a team and Pytal and removed request for a team October 9, 2024 17:15
@skjnldsv skjnldsv added 3. to review Waiting for reviews and removed 2. developing Work in progress labels Oct 9, 2024
@skjnldsv
Copy link
Member Author

skjnldsv commented Oct 9, 2024

All green and ready 🚀

Copy link
Contributor

@come-nc come-nc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed PHP changes only

apps/files_sharing/appinfo/routes.php Show resolved Hide resolved
apps/files_sharing/lib/ExpireSharesJob.php Outdated Show resolved Hide resolved
apps/files_sharing/lib/ExpireSharesJob.php Outdated Show resolved Hide resolved
lib/private/Share20/Manager.php Outdated Show resolved Hide resolved
Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
@skjnldsv
Copy link
Member Author

Addressed @come-nc

/**
* @psalm-import-type Files_SharingShare from ResponseDefinitions
*/
abstract class ShareApiControllerFactory extends OCSController {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
abstract class ShareApiControllerFactory extends OCSController {
abstract class ShareApiControllerBase extends OCSController {

I’m still unhappy with the name, this is not a factory.
See https://en.wikipedia.org/wiki/Factory_method_pattern
A Factory has static methods to create instances. This here is simply a base to be used as parent by other controllers.

Comment on lines +41 to +53
protected ShareManager $shareManager,
protected ?string $userId,
protected IUserManager $userManager,
protected IGroupManager $groupManager,
protected IRootFolder $rootFolder,
protected IAppManager $appManager,
protected ContainerInterface $serverContainer,
protected UserStatusManager $userStatusManager,
protected IPreview $previewManager,
protected IDateTimeZone $dateTimeZone,
protected IURLGenerator $urlGenerator,
protected IL10N $l,
protected LoggerInterface $logger,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
protected ShareManager $shareManager,
protected ?string $userId,
protected IUserManager $userManager,
protected IGroupManager $groupManager,
protected IRootFolder $rootFolder,
protected IAppManager $appManager,
protected ContainerInterface $serverContainer,
protected UserStatusManager $userStatusManager,
protected IPreview $previewManager,
protected IDateTimeZone $dateTimeZone,
protected IURLGenerator $urlGenerator,
protected IL10N $l,
protected LoggerInterface $logger,
ShareManager $shareManager,
?string $userId,
IUserManager $userManager,
IGroupManager $groupManager,
IRootFolder $rootFolder,
IAppManager $appManager,
ContainerInterface $serverContainer,
UserStatusManager $userStatusManager,
IPreview $previewManager,
IDateTimeZone $dateTimeZone,
IURLGenerator $urlGenerator,
IL10N $l,
LoggerInterface $logger,

Comment on lines +35 to +67
public function __construct(
IRequest $request,
ShareManager $shareManager,
?string $userId,
IUserManager $userManager,
IGroupManager $groupManager,
IRootFolder $rootFolder,
IAppManager $appManager,
ContainerInterface $serverContainer,
UserStatusManager $userStatusManager,
IPreview $previewManager,
IDateTimeZone $dateTimeZone,
IURLGenerator $urlGenerator,
IL10N $l,
LoggerInterface $logger,
) {
parent::__construct(
$request,
$shareManager,
$userId,
$userManager,
$groupManager,
$rootFolder,
$appManager,
$serverContainer,
$userStatusManager,
$previewManager,
$dateTimeZone,
$urlGenerator,
$l,
$logger,
);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public function __construct(
IRequest $request,
ShareManager $shareManager,
?string $userId,
IUserManager $userManager,
IGroupManager $groupManager,
IRootFolder $rootFolder,
IAppManager $appManager,
ContainerInterface $serverContainer,
UserStatusManager $userStatusManager,
IPreview $previewManager,
IDateTimeZone $dateTimeZone,
IURLGenerator $urlGenerator,
IL10N $l,
LoggerInterface $logger,
) {
parent::__construct(
$request,
$shareManager,
$userId,
$userManager,
$groupManager,
$rootFolder,
$appManager,
$serverContainer,
$userStatusManager,
$previewManager,
$dateTimeZone,
$urlGenerator,
$l,
$logger,
);
}

This one is really empty or did I miss something?

Comment on lines +70 to +85
protected IManager $shareManager,
protected IGroupManager $groupManager,
protected IUserManager $userManager,
protected IRootFolder $rootFolder,
protected IURLGenerator $urlGenerator,
protected IL10N $l,
protected IConfig $config,
protected IAppManager $appManager,
protected ContainerInterface $serverContainer,
protected IUserStatusManager $userStatusManager,
protected IPreview $previewManager,
protected IDateTimeZone $dateTimeZone,
protected LoggerInterface $logger,
protected IProviderFactory $factory,
protected IMailer $mailer,
string $userId,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
protected IManager $shareManager,
protected IGroupManager $groupManager,
protected IUserManager $userManager,
protected IRootFolder $rootFolder,
protected IURLGenerator $urlGenerator,
protected IL10N $l,
protected IConfig $config,
protected IAppManager $appManager,
protected ContainerInterface $serverContainer,
protected IUserStatusManager $userStatusManager,
protected IPreview $previewManager,
protected IDateTimeZone $dateTimeZone,
protected LoggerInterface $logger,
protected IProviderFactory $factory,
protected IMailer $mailer,
string $userId,
IManager $shareManager,
IGroupManager $groupManager,
IUserManager $userManager,
IRootFolder $rootFolder,
IURLGenerator $urlGenerator,
IL10N $l,
protected IConfig $config,
IAppManager $appManager,
ContainerInterface $serverContainer,
IUserStatusManager $userStatusManager,
IPreview $previewManager,
IDateTimeZone $dateTimeZone,
LoggerInterface $logger,
protected IProviderFactory $factory,
protected IMailer $mailer,
?string $userId,

Ideally I would also reorder to keep promoted properties together, I would say at the end (so, start with parameters from parent constructor in the same order as parent, add you own after)

protected LoggerInterface $logger,
) {
parent::__construct(Application::APP_ID, $request);
$this->currentUser = $userId;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
$this->currentUser = $userId;

Is there any added value to duplicate $this->userId into $this->currentUser?
If this is to have a clearer name, then remove the protected in front of $userId parameter to not turn it into a property, and keep $this->currentUser.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's here because it was used by the controllers before this pr.
I want to keep changes to the existing parts to a minimal.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was changed on master, so you should update your PR accordingly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I need to take that PR back 🙈

apps/files_sharing/lib/ExpireSharesJob.php Show resolved Hide resolved
@joshtrichards
Copy link
Member

Other issues this may address (did not link since I wasn't certain, but do so if appropriate please 😄 ):

Related too:

Comment on lines +36 to +49
IRequest $request,
ShareManager $shareManager,
?string $userId,
IUserManager $userManager,
IGroupManager $groupManager,
IRootFolder $rootFolder,
IAppManager $appManager,
ContainerInterface $serverContainer,
UserStatusManager $userStatusManager,
IPreview $previewManager,
IDateTimeZone $dateTimeZone,
IURLGenerator $urlGenerator,
IL10N $l,
LoggerInterface $logger,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where are these properties and their access modifiers defined?

Comment on lines +166 to +174
$groupShares = $this->shareManager->getExpiredShares($this->userId, IShare::TYPE_GROUP, null, -1, 0);
$roomShares = $this->shareManager->getExpiredShares($this->userId, IShare::TYPE_ROOM, null, -1, 0);
$deckShares = $this->shareManager->getExpiredShares($this->userId, IShare::TYPE_DECK, null, -1, 0);
$sciencemeshShares = $this->shareManager->getExpiredShares($this->userId, IShare::TYPE_SCIENCEMESH, null, -1, 0);
$linkShares = $this->shareManager->getExpiredShares($this->userId, IShare::TYPE_LINK, null, -1, 0);
$userShares = $this->shareManager->getExpiredShares($this->userId, IShare::TYPE_USER, null, -1, 0);
$emailsShares = $this->shareManager->getExpiredShares($this->userId, IShare::TYPE_EMAIL, null, -1, 0);
$circlesShares = $this->shareManager->getExpiredShares($this->userId, IShare::TYPE_CIRCLE, null, -1, 0);
$remoteShares = $this->shareManager->getExpiredShares($this->userId, IShare::TYPE_REMOTE, null, -1, 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No way to get all? shareType -1, could be default parameter in share Manager that returns all?

Comment on lines +166 to +174
$groupShares = $this->shareManager->getExpiredShares($this->userId, IShare::TYPE_GROUP, null, -1, 0);
$roomShares = $this->shareManager->getExpiredShares($this->userId, IShare::TYPE_ROOM, null, -1, 0);
$deckShares = $this->shareManager->getExpiredShares($this->userId, IShare::TYPE_DECK, null, -1, 0);
$sciencemeshShares = $this->shareManager->getExpiredShares($this->userId, IShare::TYPE_SCIENCEMESH, null, -1, 0);
$linkShares = $this->shareManager->getExpiredShares($this->userId, IShare::TYPE_LINK, null, -1, 0);
$userShares = $this->shareManager->getExpiredShares($this->userId, IShare::TYPE_USER, null, -1, 0);
$emailsShares = $this->shareManager->getExpiredShares($this->userId, IShare::TYPE_EMAIL, null, -1, 0);
$circlesShares = $this->shareManager->getExpiredShares($this->userId, IShare::TYPE_CIRCLE, null, -1, 0);
$remoteShares = $this->shareManager->getExpiredShares($this->userId, IShare::TYPE_REMOTE, null, -1, 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No way to get all? shareType -1, could be default parameter in share Manager that returns all?

@@ -42,13 +41,16 @@ public function __construct(ITimeFactory $time, IManager $shareManager, IDBConne
* @param array $argument unused argument
*/
public function run($argument) {
//Current time
if ($this->config->getValueString('core', 'shareapi_delete_on_expire', 'yes') === 'no') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this would be a thing for config.php... We should

  • Update config.sample.php that is an in code source documentation
  • Document this somewhere the administration manual

private $serverContainer;

public function __construct(string $appName,
class DeletedShareAPIController extends ShareApiControllerFactory {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick : Is this BaseShareApiController or Factory? Factories are to help easy object creation, testing, decoupling not exactly DRY-ing?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Keep list of expired public shares
6 participants